"""
测试运行器 - 运行所有测试套件

用法：
python -m test.run_all_tests [options]

选项：
  --basic      只运行基本功能测试
  --locking    只运行锁机制测试
  --threading  只运行多线程测试
  --integration 只运行集成测试
  --performance 只运行性能测试
  --quick      快速测试（跳过性能测试）
  --verbose    详细输出
  --report     生成测试报告
"""

import sys
import argparse
import time
import os
from typing import Dict, List, Tuple

# 添加父目录到Python路径以便导入模块
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
if parent_dir not in sys.path:
    sys.path.insert(0, parent_dir)

# 导入测试模块
try:
    from test_basic import run_basic_tests
    from test_locking import run_locking_tests
    from test_multithreading import run_multithreading_tests
    from test_integration import run_integration_tests
    from test_performance import run_performance_tests
except ImportError as e:
    print(f"导入测试模块失败: {e}")
    print(f"当前目录: {current_dir}")
    print(f"父目录: {parent_dir}")
    print(f"Python路径: {sys.path[:3]}")
    sys.exit(1)


class TestRunner:
    """测试运行器"""
    
    def __init__(self, verbose: bool = False, generate_report: bool = False):
        self.verbose = verbose
        self.generate_report = generate_report
        self.test_results = {}
        self.start_time = time.time()
    
    def run_test_suite(self, name: str, test_function) -> bool:
        """运行单个测试套件"""
        print(f"\n{'='*60}")
        print(f"开始运行 {name} 测试套件")
        print(f"{'='*60}")
        
        suite_start = time.time()
        
        try:
            success = test_function()
            suite_end = time.time()
            duration = suite_end - suite_start
            
            self.test_results[name] = {
                'success': success,
                'duration': duration,
                'error': None
            }
            
            status = "✅ 通过" if success else "❌ 失败"
            print(f"\n{name} 测试套件 {status} (耗时: {duration:.2f}秒)")
            
            return success
            
        except Exception as e:
            suite_end = time.time()
            duration = suite_end - suite_start
            
            self.test_results[name] = {
                'success': False,
                'duration': duration,
                'error': str(e)
            }
            
            print(f"\n{name} 测试套件 ❌ 错误: {e} (耗时: {duration:.2f}秒)")
            return False
    
    def run_all_tests(self, test_selection: Dict[str, bool] = None) -> bool:
        """运行所有或选定的测试"""
        if test_selection is None:
            test_selection = {
                'basic': True,
                'locking': True,
                'threading': True,
                'integration': True,
                'performance': True
            }
        
        print("🚀 开始运行数据库系统测试套件")
        print(f"测试范围: {', '.join([k for k, v in test_selection.items() if v])}")
        
        all_success = True
        
        # 按顺序运行测试
        test_order = [
            ('基本功能', 'basic', run_basic_tests),
            ('锁机制', 'locking', run_locking_tests),
            ('多线程', 'threading', run_multithreading_tests),
            ('系统集成', 'integration', run_integration_tests),
            ('性能基准', 'performance', run_performance_tests)
        ]
        
        for display_name, key, test_func in test_order:
            if test_selection.get(key, False):
                success = self.run_test_suite(display_name, test_func)
                if not success:
                    all_success = False
                    
                    # 如果基础测试失败，询问是否继续
                    if key == 'basic':
                        response = input("\n基础测试失败，是否继续运行其他测试？(y/N): ")
                        if response.lower() not in ['y', 'yes']:
                            break
        
        return all_success
    
    def print_summary(self):
        """打印测试总结"""
        total_time = time.time() - self.start_time
        
        print(f"\n{'='*60}")
        print("🎯 测试总结")
        print(f"{'='*60}")
        
        total_tests = len(self.test_results)
        passed_tests = sum(1 for r in self.test_results.values() if r['success'])
        failed_tests = total_tests - passed_tests
        
        print(f"📊 总体统计:")
        print(f"  • 运行的测试套件: {total_tests}")
        print(f"  • 通过的测试套件: {passed_tests}")
        print(f"  • 失败的测试套件: {failed_tests}")
        print(f"  • 总耗时: {total_time:.2f}秒")
        print(f"  • 成功率: {passed_tests/total_tests*100:.1f}%")
        
        print(f"\n📋 详细结果:")
        for name, result in self.test_results.items():
            status = "✅" if result['success'] else "❌"
            duration = result['duration']
            print(f"  {status} {name:<12} {duration:>8.2f}s")
            
            if not result['success'] and result['error']:
                print(f"      错误: {result['error']}")
        
        if failed_tests == 0:
            print(f"\n🎉 所有测试都通过了！数据库系统运行正常。")
        else:
            print(f"\n⚠️  有 {failed_tests} 个测试套件失败，请检查相关功能。")
        
        # 性能总结
        if '性能基准' in self.test_results:
            perf_result = self.test_results['性能基准']
            if perf_result['success']:
                print(f"\n🚀 性能测试通过，系统性能指标符合预期。")
        
        # 建议
        self._print_recommendations()
    
    def _print_recommendations(self):
        """打印改进建议"""
        print(f"\n💡 改进建议:")
        
        failed_tests = [name for name, result in self.test_results.items() if not result['success']]
        
        if not failed_tests:
            print("  • 系统运行良好，可以考虑增加更多功能测试")
            print("  • 建议定期运行性能测试监控系统性能")
            print("  • 可以考虑添加更复杂的并发场景测试")
        else:
            if '基本功能' in failed_tests:
                print("  • 优先修复基本功能问题，这是系统的基础")
            if '锁机制' in failed_tests:
                print("  • 检查锁管理器的实现，确保并发安全")
            if '多线程' in failed_tests:
                print("  • 优化线程池配置和线程安全实现")
            if '系统集成' in failed_tests:
                print("  • 检查模块间的集成和数据一致性")
            if '性能基准' in failed_tests:
                print("  • 分析性能瓶颈，优化关键路径")
    
    def generate_report(self):
        """生成测试报告"""
        if not self.generate_report:
            return
        
        report_content = self._create_report_content()
        
        # 保存到文件
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        report_file = f"test_report_{timestamp}.md"
        
        try:
            with open(report_file, 'w', encoding='utf-8') as f:
                f.write(report_content)
            print(f"\n📄 测试报告已保存到: {report_file}")
        except Exception as e:
            print(f"\n❌ 保存测试报告失败: {e}")
    
    def _create_report_content(self) -> str:
        """创建测试报告内容"""
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        total_time = time.time() - self.start_time
        
        content = f"""# 数据库系统测试报告

## 测试信息
- **测试时间**: {timestamp}
- **总耗时**: {total_time:.2f}秒
- **测试环境**: Python {sys.version.split()[0]}

## 测试结果总览

| 测试套件 | 状态 | 耗时(秒) | 备注 |
|---------|------|----------|------|
"""
        
        for name, result in self.test_results.items():
            status = "✅ 通过" if result['success'] else "❌ 失败"
            duration = result['duration']
            note = result['error'] if result['error'] else "-"
            content += f"| {name} | {status} | {duration:.2f} | {note} |\n"
        
        # 统计信息
        total_tests = len(self.test_results)
        passed_tests = sum(1 for r in self.test_results.values() if r['success'])
        
        content += f"""
## 统计信息
- **总测试套件数**: {total_tests}
- **通过测试数**: {passed_tests}
- **失败测试数**: {total_tests - passed_tests}
- **成功率**: {passed_tests/total_tests*100:.1f}%

## 详细分析
"""
        
        for name, result in self.test_results.items():
            content += f"\n### {name}\n"
            if result['success']:
                content += "- **状态**: ✅ 通过\n"
                content += f"- **耗时**: {result['duration']:.2f}秒\n"
                content += "- **说明**: 测试正常完成\n"
            else:
                content += "- **状态**: ❌ 失败\n"
                content += f"- **耗时**: {result['duration']:.2f}秒\n"
                if result['error']:
                    content += f"- **错误**: {result['error']}\n"
                content += "- **建议**: 请检查相关功能实现\n"
        
        content += """
## 系统评估

基于测试结果，系统的各项功能表现如下：

### 功能完整性
- 基本存储功能
- 并发控制机制
- 多线程支持
- 系统集成度

### 性能表现
- 读写性能
- 并发处理能力
- 内存使用效率
- 缓存命中率

### 稳定性
- 错误处理能力
- 资源管理
- 长时间运行稳定性

---
*报告由数据库系统测试套件自动生成*
"""
        
        return content


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='数据库系统测试套件')
    
    # 测试选择选项
    parser.add_argument('--basic', action='store_true', help='只运行基本功能测试')
    parser.add_argument('--locking', action='store_true', help='只运行锁机制测试')
    parser.add_argument('--threading', action='store_true', help='只运行多线程测试')
    parser.add_argument('--integration', action='store_true', help='只运行集成测试')
    parser.add_argument('--performance', action='store_true', help='只运行性能测试')
    parser.add_argument('--quick', action='store_true', help='快速测试（跳过性能测试）')
    
    # 输出选项
    parser.add_argument('--verbose', '-v', action='store_true', help='详细输出')
    parser.add_argument('--report', '-r', action='store_true', help='生成测试报告')
    
    args = parser.parse_args()
    
    # 确定要运行的测试
    test_selection = {}
    
    if any([args.basic, args.locking, args.threading, args.integration, args.performance]):
        # 如果指定了特定测试，只运行这些
        test_selection = {
            'basic': args.basic,
            'locking': args.locking,
            'threading': args.threading,
            'integration': args.integration,
            'performance': args.performance
        }
    elif args.quick:
        # 快速测试，跳过性能测试
        test_selection = {
            'basic': True,
            'locking': True,
            'threading': True,
            'integration': True,
            'performance': False
        }
    else:
        # 默认运行所有测试
        test_selection = {
            'basic': True,
            'locking': True,
            'threading': True,
            'integration': True,
            'performance': True
        }
    
    # 创建并运行测试
    runner = TestRunner(verbose=args.verbose, generate_report=args.report)
    
    try:
        success = runner.run_all_tests(test_selection)
        runner.print_summary()
        runner.generate_report()
        
        # 根据测试结果设置退出码
        sys.exit(0 if success else 1)
        
    except KeyboardInterrupt:
        print("\n\n⚠️  测试被用户中断")
        runner.print_summary()
        sys.exit(2)
    except Exception as e:
        print(f"\n❌ 测试运行器出现错误: {e}")
        sys.exit(3)


if __name__ == "__main__":
    main()
